from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
import json


class GitLabServer(models.Model):
    """GitLab服务器配置"""
    name = models.CharField(max_length=100, verbose_name='服务器名称')
    url = models.URLField(verbose_name='GitLab URL')
    token = models.CharField(max_length=255, verbose_name='访问Token')
    description = models.TextField(blank=True, null=True, verbose_name='描述')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')

    # 连接状态
    status = models.CharField(
        max_length=20,
        choices=[
            ('connected', '已连接'),
            ('disconnected', '连接失败'),
            ('error', '错误'),
            ('testing', '测试中'),
        ],
        default='disconnected',
        verbose_name='连接状态'
    )

    # 统计信息
    project_count = models.IntegerField(default=0, verbose_name='项目数量')
    user_count = models.IntegerField(default=0, verbose_name='用户数量')

    # 时间戳
    last_sync = models.DateTimeField(null=True, blank=True, verbose_name='最后同步时间')
    last_check = models.DateTimeField(null=True, blank=True, verbose_name='最后检查时间')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = 'GitLab服务器'
        verbose_name_plural = 'GitLab服务器'
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.name} ({self.url})"


class Project(models.Model):
    """项目表 - 用于权限控制"""
    name = models.CharField(max_length=100, verbose_name='项目名称')
    code = models.CharField(max_length=50, unique=True, verbose_name='项目代码')
    description = models.TextField(blank=True, null=True, verbose_name='项目描述')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '项目'
        verbose_name_plural = '项目'
        ordering = ['name']

    def __str__(self):
        return self.name


class Environment(models.Model):
    """环境表 - 用于权限控制"""
    name = models.CharField(max_length=50, verbose_name='环境名称')
    code = models.CharField(max_length=20, unique=True, verbose_name='环境代码')
    description = models.TextField(blank=True, null=True, verbose_name='环境描述')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '环境'
        verbose_name_plural = '环境'
        ordering = ['name']

    def __str__(self):
        return self.name


class UserProjectPermission(models.Model):
    """用户项目权限表"""
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='用户')
    project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='项目')
    environment = models.ForeignKey(Environment, on_delete=models.CASCADE, verbose_name='环境')

    # 权限类型
    can_view = models.BooleanField(default=True, verbose_name='查看权限')
    can_edit = models.BooleanField(default=False, verbose_name='编辑权限')
    can_delete = models.BooleanField(default=False, verbose_name='删除权限')
    can_deploy = models.BooleanField(default=False, verbose_name='部署权限')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '用户项目权限'
        verbose_name_plural = '用户项目权限'
        unique_together = ['user', 'project', 'environment']

    def __str__(self):
        return f"{self.user.username} - {self.project.name} - {self.environment.name}"


class GitLabProject(models.Model):
    """GitLab项目"""
    gitlab_server = models.ForeignKey(GitLabServer, on_delete=models.CASCADE, verbose_name='GitLab服务器')
    project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True, blank=True, verbose_name='关联项目')
    environment = models.ForeignKey(Environment, on_delete=models.CASCADE, null=True, blank=True, verbose_name='关联环境')

    # GitLab项目信息
    gitlab_id = models.IntegerField(verbose_name='GitLab项目ID')
    name = models.CharField(max_length=255, verbose_name='项目名称')
    path = models.CharField(max_length=255, verbose_name='项目路径')
    path_with_namespace = models.CharField(max_length=500, verbose_name='完整路径')
    description = models.TextField(blank=True, null=True, verbose_name='项目描述')

    # 项目URLs
    web_url = models.URLField(verbose_name='Web URL')
    ssh_url_to_repo = models.CharField(max_length=500, verbose_name='SSH URL')
    http_url_to_repo = models.CharField(max_length=500, verbose_name='HTTP URL')

    # 项目状态
    visibility = models.CharField(max_length=20, verbose_name='可见性')
    default_branch = models.CharField(max_length=100, blank=True, null=True, verbose_name='默认分支')

    # 统计信息
    star_count = models.IntegerField(default=0, verbose_name='星标数')
    forks_count = models.IntegerField(default=0, verbose_name='分支数')

    # 时间戳
    last_activity_at = models.DateTimeField(null=True, blank=True, verbose_name='最后活动时间')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = 'GitLab项目'
        verbose_name_plural = 'GitLab项目'
        unique_together = ['gitlab_server', 'gitlab_id']
        ordering = ['-last_activity_at']

    def __str__(self):
        return f"{self.gitlab_server.name} - {self.path_with_namespace}"


class GitLabUser(models.Model):
    """GitLab用户"""
    gitlab_server = models.ForeignKey(GitLabServer, on_delete=models.CASCADE, verbose_name='GitLab服务器')
    local_user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='关联本地用户')

    # GitLab用户信息
    gitlab_id = models.IntegerField(verbose_name='GitLab用户ID')
    username = models.CharField(max_length=255, verbose_name='用户名')
    name = models.CharField(max_length=255, verbose_name='姓名')
    email = models.EmailField(verbose_name='邮箱')

    # 用户状态
    state = models.CharField(max_length=20, verbose_name='状态')
    is_admin = models.BooleanField(default=False, verbose_name='是否管理员')

    # 用户信息
    avatar_url = models.URLField(blank=True, null=True, verbose_name='头像URL')
    web_url = models.URLField(verbose_name='用户主页URL')

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = 'GitLab用户'
        verbose_name_plural = 'GitLab用户'
        unique_together = ['gitlab_server', 'gitlab_id']
        ordering = ['username']

    def __str__(self):
        return f"{self.gitlab_server.name} - {self.username}"


class GitLabAudit(models.Model):
    """GitLab操作审计"""
    gitlab_server = models.ForeignKey(GitLabServer, on_delete=models.CASCADE, verbose_name='GitLab服务器')
    gitlab_project = models.ForeignKey(GitLabProject, on_delete=models.CASCADE, null=True, blank=True, verbose_name='关联项目')
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='操作用户')

    # 操作信息
    operation_type = models.CharField(
        max_length=50,
        choices=[
            ('gitlab_project_create', '项目创建'),
            ('gitlab_project_update', '项目更新'),
            ('gitlab_project_delete', '项目删除'),
            ('gitlab_commit', '代码提交'),
            ('gitlab_merge', '代码合并'),
            ('gitlab_tag', '标签操作'),
            ('gitlab_pipeline', '流水线'),
            ('gitlab_user_sync', '用户同步'),
            ('gitlab_server_test', '服务器测试'),
            ('gitlab_webhook_config', 'Webhook配置'),
        ],
        verbose_name='操作类型'
    )

    target_name = models.CharField(max_length=255, verbose_name='操作目标')
    description = models.TextField(verbose_name='操作描述')

    # 操作结果
    result = models.CharField(
        max_length=20,
        choices=[
            ('success', '成功'),
            ('failed', '失败'),
        ],
        verbose_name='操作结果'
    )

    # 详细信息
    details = models.JSONField(default=dict, blank=True, verbose_name='详细信息')
    error_message = models.TextField(blank=True, null=True, verbose_name='错误信息')

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='操作时间')

    class Meta:
        verbose_name = 'GitLab操作审计'
        verbose_name_plural = 'GitLab操作审计'
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.operation_type} - {self.target_name} - {self.result}"


class DevOpsTimeline(models.Model):
    """DevOps操作时间线"""
    project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='项目')
    environment = models.ForeignKey(Environment, on_delete=models.CASCADE, verbose_name='环境')
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='操作用户')

    # 事件信息
    event_type = models.CharField(
        max_length=50,
        choices=[
            ('gitlab_commit', 'GitLab提交'),
            ('gitlab_merge', 'GitLab合并'),
            ('jenkins_build', 'Jenkins构建'),
            ('jenkins_deploy', 'Jenkins部署'),
        ],
        verbose_name='事件类型'
    )

    title = models.CharField(max_length=255, verbose_name='事件标题')
    description = models.TextField(verbose_name='事件描述')

    # 关联信息
    gitlab_project = models.ForeignKey(GitLabProject, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='GitLab项目')

    # 事件状态
    status = models.CharField(
        max_length=20,
        choices=[
            ('success', '成功'),
            ('failed', '失败'),
            ('running', '进行中'),
            ('pending', '等待中'),
        ],
        verbose_name='事件状态'
    )

    # 详细信息
    details = models.JSONField(default=dict, blank=True, verbose_name='详细信息')

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='事件时间')

    class Meta:
        verbose_name = 'DevOps时间线'
        verbose_name_plural = 'DevOps时间线'
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.event_type} - {self.title}"
